package com.seata.demo.storage.config;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import io.seata.rm.datasource.DataSourceProxy;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.transaction.SpringManagedTransactionFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;

@Configuration
public class DataSourceConfig {

    /**
     * 1. 配置原始数据源（HikariCP为例，也可替换为其他连接池）
     */
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")  // 读取application.yml中的数据源配置
    public HikariConfig hikariConfig() {
        return new HikariConfig();
    }

    /**
     * 2. 用Seata的DataSourceProxy包装原始数据源
     */
    @Bean
    public DataSource dataSource(HikariConfig hikariConfig) {
        HikariDataSource hikariDataSource = new HikariDataSource(hikariConfig);
        // 显式创建Seata数据源代理（AT模式必须）
        return new DataSourceProxy(hikariDataSource);
    }

    /**
     * 3. 配置MyBatis的SqlSessionFactory，使用Seata代理的数据源
     */
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        // 设置Seata代理后的数据源
        sqlSessionFactoryBean.setDataSource(dataSource);
        // 配置MyBatis映射文件路径
        sqlSessionFactoryBean.setMapperLocations(
            new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml")
        );
        // 使用Spring管理的事务工厂（与Seata兼容）
        sqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory());
        return sqlSessionFactoryBean;
    }
}
